home *** CD-ROM | disk | FTP | other *** search
-
- SiFLyiNG
- Tutorial #9
-
- ____________________________________________________________________________
-
- Target : Liquid Crackme 1
- d/l it on http://crackmes.cjb.net
- Protection type : Serial/name
- Level : Classic serial generation
- Tools needed : I've only use SoftIce
- Basis of cracking
- A brain (optional ;)
- Punk mp3 (Bad religion & Millencolin for the moment)
- I must be enough... :)
- ____________________________________________________________________________
-
- Before beginning...
-
- This crackme is 'classic'. I mean it's a Serial/name protection and
- the serial is generated from the name. All the char are used for this
- calculation. I have nothing more to say as introduction... Time is money,
- so let's start.
-
- ____________________________________________________________________________
-
- The essay...
-
- There are two textbox in the main form of the crackme :
- 1. "Enter your name here:" : name
- 2. "And the serial is:" : serial
-
- So we'll complete them with 'SiFLyiNG' and '12345678'. A 'bpx hmemcpy'
- in Softice will be better, then we just press the check button and we're back
- to SoftIce. From there you press F11 one time to return to the caller, and
- F12 til you see at the bottom of the code window :
-
- CRACKME1!CODE+00026242 (i believe you'll see the same...)
-
- NB: if we had just wanted to get the real serial for our name, we would have
- to make another F5 and follow the same step afterwards (F11 and F12), so that
- the crackme could have got the two entries (name and serial). There, we would
- have arrived just at the beginning of the serial check, and it would have been
- easy to get the valid serial from there. But we won't just get a valid serial,
- we'll see the calculation routine too, in order to code a keygen.
-
- So, now you should see this piece of code :
-
- :00427239 lea edx, dword ptr [ebp-10]
- :0042723C mov eax, dword ptr [edi+000001B4]
- :00427242 call 00411AC8 ; get the entered name
- :00427247 mov eax, dword ptr [ebp-10] ; <-- Here you land
- ; after this line, eax points to the name
- :0042724A call 00403380 ; this call returns the len of the entered name
- :0042724F mov dword ptr [ebp-04], eax ; stores the lenght of name
- :00427252 cmp dword ptr [ebp-04], 00000004 ; compare the lenght with 4
- :00427256 jge 00427272 ; lenght must be superior or equal to 4
- ; if it's the case, jump and go on checking
- ; otherwise, displays a message box :
- ; "Your name must have at least 4 characters!"
- :00427258 push 00000000
- :0042725A mov cx, word ptr [00427354]
- :00427261 xor edx, edx
- :00427263 mov eax, 00427360
- :00427268 call 00426CAC ; displays the message box
- :0042726D jmp 00427327
-
- Fortunately, the lenght of name 'SiFLyiNG' is longer than 4 characters, so we
- jump from 427256 to 427272 and we arrive here:
-
- :00427272 mov eax, dword ptr [ebp-04] ; eax = lenght of name
- :00427275 test eax, eax ; check if name entered
- :00427277 jle 004272CE ; jump to bad cracker
- :00427279 mov dword ptr [ebp-0C], eax ; store the lenght of name in [EBP-0C]
- :0042727C mov esi, 00000001 ; esi = 1
-
- OK, this is not interesting for the moment but if we trace a bit in
- the code, we arrive in a loop which begins the serial calculation :
-
- :00427281 lea edx, dword ptr [ebp-10]
- :00427284 mov eax, dword ptr [edi+000001B4]
- :0042728A call 00411AC8 ; this call gets the name (same as the
- ; previous)
- :0042728F mov eax, dword ptr [ebp-10] ; eax points to the name
- :00427292 movzx eax, byte ptr [eax+esi-01] ; eax = ascii value of the ESIth
- ; char from name (from the beginning)
- :00427297 mov dword ptr [ebp-08], eax ; store eax in [EBP-08]
- :0042729A lea edx, dword ptr [ebp-10]
- :0042729D mov eax, dword ptr [edi+000001B4]
- :004272A3 call 00411AC8 ; this call gets the name another time
- :004272A8 mov eax, dword ptr [ebp-10] ; eax points to the name
- :004272AB mov edx, dword ptr [ebp-04] ; edx = lenght of name
- :004272AE sub edx, esi ; edx - esi
- :004272B0 movzx eax, byte ptr [eax+edx-01] ; eax = ascii value of the EDXth
- ; char from the name
- :004272B5 and dword ptr [ebp-08], eax ; [EBP-08] AND EAX
- :004272B8 add ebx, dword ptr [ebp-08] ; ebx = ebx+[EBP-08]
- :004272BB imul ebx, esi ; ebx * esi
- :004272BE test ebx, ebx ; check if EBX> or = 0
- :004272C0 jge 004272C8 ; jump if greater or equal
- :004272C2 mov eax, ebx ; eax= ebx
- :004272C4 neg eax ; takes the two's complement of eax
- :004272C6 mov ebx, eax ; ebx = eax
- :004272C8 inc esi ; next char
- :004272C9 dec [ebp-0C] ; dec [ebp-0C] (equal to lenght at the beginning
- :004272CC jne 00427281 ; if there are char left -> loop again
- ; otherwise, finish the loop
-
- Waouhh... we are near the end :) This loop is the main part of the
- calculation routine. I explain it in details, so that it'll be easily to
- keygen the crackme. What does this loop do ???
-
- * First loop : characters used from SiFLyiNG are S(1) and N(len-1-1)
-
- movzx eax, byte ptr [eax+esi-01] ; EAX = 53h = value of 'S'
- mov dword ptr [ebp-08], eax ; [EBP-08] = EAX = 53h
- movzx eax, byte ptr [eax+edx-01] ; EAX = 47h = value of 'N'
- and dword ptr [ebp-08], eax ; [EBP-08] = 53h AND 4Eh = 42h
- add ebx, dword ptr [ebp-08] ; EBX = EBX + [EBP-08]
- before the first loop, EBX=B953E0h, so EBX = EBX+[EBP-08]=B953E0h+42h=B95422h
- imul ebx, esi ; EBX = EBX * 1
- EBX>0 so it jumps to 004272C8 and [EBP-0C]-1 = 8-1 = 7
- and 7<>0 so it loops another time and we get :
-
- * Second Loop : characters used are i(2) and i(len-2-1)
-
- movzx eax, byte ptr [eax+esi-01] ; EAX = 69h = value of 'i'
- mov dword ptr [ebp-08], eax ; [EBP-08] = EAX = 69h
- movzx eax, byte ptr [eax+edx-01] ; EAX = 69h = value of 'i'
- and dword ptr [ebp-08], eax ; [EBP-08] = 69h AND 69h = 69h
- add ebx, dword ptr [ebp-08] ; EBX = EBX + [EBP-08]
- so EBX = B95422h + 69h = B9548Bh
- imul ebx, esi ; EBX=EBX*2=172A916h
- EBX>0 so it jumps to 004272C8 and [EBP-0C]-1 = 6
- 6 <> 0 so it loops another time...
-
- * Last Loop : characters used from name are G(last char), but char(len-len-1)
- doesn't exist so :
-
- and dword ptr [ebp-08], eax ; result is 00
- add ebx, dword ptr [ebp-08] ; EBX doesn't change=40B42778h
- imul ebx, esi ; EBX * 8 = 05A13BC0h
-
- Thus, at the end of the loop we have : EBX=05A13BC0h
-
- Let's summarizes what the loop makes in general:
-
- EBX = B953E0 before the first loop
-
- For i = 1 to lenght of name:
- 1. Takes value of char(i)
- 2. Takes value of char(len-i-1)
- 3. Logical AND between these two values
- 4. The result is add to EBX
- 5. EBX=EBX*i
- 6. There is a test: EBX>0 ?
-
- What does it mean ??? this test check if EBX<8000 0000h... why this value ?
- To see why, make these three examples:
- type '? 7FFFFFFF' in Softice : you see the value in hexa and decimal
- type '? 80000000':you see the value in hexa and in decimal and
- something between brackets
- type '? 80000001';you see the hex and dec value, and something strange
- between brackets:decimal signed value with a minus sign.
- You understand now ? All hexa values upper to 80000000 and inferior or
- equal to FFFFFFFFh are negative. 80000000 is the maximum negative number
- and FFFFFFFF the minimum (it's equal to -1). That's why the prog check if
- EBX is superior or equal to 0, and in the other case it takes the two's
- complement of EBX. Remember it, that could be important for keygening...
- So, we have the two case:
-
- Yes: | No:
- (2356574h for example) | (80001234h for example or FF123456h)
- 7. Next step | 7. Neg EBX means EBX=-EBX (reverse the sign)
- |
-
- 8. Next loop (means i=i+1)
-
- I think it's understandable enough now... Let's see what happens
- afterwards :
-
- :004272CE mov eax, ebx ; eax = ebx
- :004272D0 imul ebx ; eax = eax * ebx = ebx²
- :004272D2 mov ebx, eax ; ebx = eax
- :004272D4 lea edx, dword ptr [ebp-14]
- :004272D7 mov eax, ebx ; eax =ebx
- :004272D9 call 004054EC ; this call converts eax to a string
- :004272DE mov eax, dword ptr [ebp-14]
- :004272E1 push eax ; push the converted string
- :004272E2 lea edx, dword ptr [ebp-10]
- :004272E5 mov eax, dword ptr [edi+000001BC]
- :004272EB call 00411AC8 ; this call gets the entered serial
- :004272F0 mov edx, dword ptr [ebp-10] ; edx points to the serial
- :004272F3 pop eax ; eax points to the converted string
- :004272F4 call 00403490 ; comparison between the two strings
- :004272F9 jne 00427312 ; jump to bad cracker if they are differents
-
- Hummm... i think it's clear, doesn't it ??? The famous converted
- string is in fact the real serial for the name 'SiFLyiNG'. You should find
- '-1250816000'. But how has the crackme calculated this value ???
- Here are the importants lines :
-
- :004272CE mov eax, ebx ; EAX = EBX = 05A13BC0h
- :004272D0 imul ebx ; EAX = 05A13BC0h * 05A13BC0h = B5721000h
- :004272D2 mov ebx, eax ; EBX = B5721000h
- :004272D4 lea edx, dword ptr [ebp-14]
- :004272D7 mov eax, ebx ; EAX = B5721000h
- :004272D9 call 004054EC ; this call converts eax to a string
- :004272DE mov eax, dword ptr [ebp-14] ; EAX points to the Valid Serial
- :004272E1 push eax ; Push the valid serial
-
- A simple EBX=EBX*EBX is used. But we have EBX=B5721000h.
- Let's try to convert it in SoftIce :
-
- '? B5721000' and we see :
-
- B5721000 3044151296 (-1250816000)
-
- So this conversion is signed. Instead of getting 3044151296 as we could have
- thought, we finally have -1250816000. This is very important to make a
- keygen.
-
- ____________________________________________________________________________
-
- The end...
-
- I hope this tut was useful... and most of all understandable !!! I
- prefered to detail the routine in order to make a keygen because i think
- it's more interesting that serial sniffing, which is here quite easy.
- Now try to make your own keygen ! and if you have questions, critics
- or anything else, just mail me.
- Regards,
- SiFLyiNG
- siflying@ifrance.com
-
-
- Greetz : ACiD BuRN, Eternal Bliss, Magic Raphoun, Lucifer48
- Skymarshall, Volatility, VisionZ, AB4DS, Liquid
- and all the authors of crackme and tutorials...
-
- PS : i'm looking for Win32asm source for keygen and crackme... if you have
- some please send them to me...
-
-
-
-
-
-
-
-
-
-
-
-
-
-